/*
** my_malloc.c for malloc in /home/dubois_e//Downloads/malloc/1
** 
** Made by remi dubois
** Login   <dubois_e@epitech.net>
** 
** Started on  Wed Jan 30 11:15:09 2013 remi dubois
** Last update Fri Feb  8 17:27:39 2013 remi dubois
*/

#include	"my_malloc.h"

data	*first = NULL;

void	show_alloc_mem(void)
{
  data	*tmp;

  tmp = first;
  while (tmp != NULL)
    {
      if (tmp->empty == 0)
	printf("%p - %p : %i octets\n",
	       tmp + sizeof(*tmp),
	       tmp + sizeof(*tmp) + tmp->size,
	       tmp->size);
      tmp = tmp->next;
    }
}

void	end_page(data *tmp, size_t taille, size_t empty_size)
{
  data	*new;

  new = (void *)tmp + (sizeof(*tmp) + taille);
  new->empty = 1;
  new->size = empty_size - (sizeof(*new));
  new->next = tmp->next;
  tmp->next = new;
  tmp->size = taille;
}

int		check(size_t taille)
{
  struct rlimit	limit;

  getrlimit(RLIMIT_DATA, &limit);
  if (taille <= 0 || taille > (limit.rlim_cur / 2))
    return (1);
  if (first == NULL)
    {
      first = sbrk(sizeof(*first));
      first->empty = 0;
      first->size = 0;
      first->next = NULL;
    }
  return (0);
}

void	*malloc(size_t taille)
{
  data	*new = NULL;
  data	*tmp = NULL;
  data	*tmp2 = NULL;

  if (check(taille))
    return (NULL);
  for (tmp2 = first; tmp2 != NULL; tmp2 = tmp2->next)
    {
      tmp = tmp2;
      if (tmp->size >= taille && tmp->empty == 1)
	{
	  tmp->empty = 0;
	  if (tmp->size != taille && sizeof(*tmp) < tmp->size - taille)
	    end_page(tmp, taille, (tmp->size - (taille)));
	  return ((void *)tmp + sizeof(*tmp));
	}
    }
  if ((taille + sizeof(*new)) < (size_t)getpagesize())
    {
      if ((new = sbrk(getpagesize())) == (void *) -1)
	return (NULL);
      new->next = NULL;
      end_page(new, taille, (getpagesize() - (taille + sizeof(*new))));
    }
  else
    {
      if ((new = sbrk(sizeof(*new) + taille)) == (void *) - 1)
	return (NULL);
      new->next = NULL;
    }
  new->size = taille;
  new->empty = 0;
  tmp->next = new;
  return ((void *)new + sizeof(*new));
}
